package org.wen.soft.asm.model;


import lombok.Data;
import org.objectweb.asm.Type;
import java.util.ArrayList;
import java.util.List;

@Data
public class LoadMethod implements ILodeMethod{

    int access;
    String name;
    String descriptor;          // 返回值、参数值信息
    String signature;           // 具备泛型的 descriptor
    String[] exceptions;
    int parameterCount = 0;

    List<LoadAnnotation> loadAnnotations = new ArrayList<>();
    List<LoadInvokeMethod> loadInvokeMethods = new ArrayList<>();
    List<LoadParameter> loadParameters = new ArrayList<>();

    public LoadMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        this.access = access;
        this.name = name;
        this.descriptor = descriptor;
        this.signature = signature;
        this.exceptions = exceptions;

        // 获得参数对象集合（按下标记录位置）
        handlerParameterType(descriptor);
    }

    public void visitAnnotation(LoadAnnotation loadAnnotation) {
        loadAnnotations.add(loadAnnotation);
    }

    public void visitInvokeMethod(LoadInvokeMethod loadInvokeMethod) {
        loadInvokeMethods.add(loadInvokeMethod);
    }


    public void visitParameter(String name, int access) {
        if (parameterCount < loadParameters.size()) {
            LoadParameter parameter = loadParameters.get(parameterCount);
            parameter.setNameAndAccess(name, access);
            parameterCount++;
        }
    }

    public void visitParameterAnnotation(int parameter, LoadAnnotation loadAnnotation) {
        if (loadParameters.size() > parameter) {
            loadParameters.get(parameter).addLoadAnnotation(loadAnnotation);
        }
    }

    private void handlerParameterType(String descriptor){
        Type type = Type.getType(descriptor);
        Type[] argumentTypes = type.getArgumentTypes();
        for (int i = 0; i < argumentTypes.length; i++) {
            loadParameters.add(new LoadParameter(i, argumentTypes[i].getDescriptor()));
        }
    }
}
